# -*- coding: utf-8 -*-
import sys
from ABJLabel import *
import PrincipalUI
from PyQt4 import QtCore
from PyQt4 import QtGui
from logico.iABJ import *
from PrincipalUI import *
from logico.problemas.acciones.IAccion import IAccion
from logico.problemas.acciones.IAbrir import IAbrir
import os
from numpy  import *
from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s
class VentanaPrincipal(QtGui.QMainWindow, PrincipalUI.Ui_MainWindow):
    
    """
    Clase principal grafica. Despliega una ventana y en su interior la interfaz completa del proyecto ABJ.
    @since: 4/14/2011
    @version: 1.0
    """

    _mochilaGrid = array ([[True,True],[True,True],[True,True]])
    
    _select_dialog = None
    
    _seleContainer = []    
    
    _sele = []
    """ Lista que contiene el valor del elemento seleccionado en el canvas """
    
    _sele_mochila = []
    """ Lista que contiene el valor del elemento seleccionado en la mochila """
    
    _logico = None
    """ Referencia al objeto logico (control) que la vista utiliza para ejecutar comandos """
    
    _lbl_heroe = None
    """ Label para despliegue del Heroe """
    
    _viejo = None
    """ ??? """
    
    _prob = ""
    """ Referencia al problema cargado """
    
    _canvas_lbls = []
    """ Arreglo de labels colocados en el canvas """
    
    _mochila_lbls = []
    """ Arreglo de labels colocados en la mochila """
    
    _show_panel_lbls = []
    """ Arreglo de labels colocados en el show panel """
    
    _i=-1
    """Contador utilizado para definir el número de entrada del log a insertar """

    _actionString=""
    """String que contiene todo lo desplegado en el log de acciones"""
        
    _labels_ayuda = []
    """ Labels de la ventana para las instrucciones del problema """
    
    def __init__(self, parent=None):
        """
        Constructor
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    parent: QObject
        @param    parent: Componente de pyQT que despliega la VentanaPrincipal
        """       
        # Setup grafico
        super(VentanaPrincipal, self).__init__(parent)        
        self.setupUi(self)
        self.connectActions()
        self.actionAbrir.triggered.connect(self.openOption)
        self.actionGuardar.triggered.connect(self.saveOption)
        self.actionCerrar.triggered.connect(QtGui.qApp.quit)
        #self.actionSeleccionar_el_heroe.triggered.connect(self.showLogPanel)
        self.action_Qu_tengo_que_hacer.triggered.connect(self.problemDescription)
        self.actionComprobar_problema.triggered.connect(self.calificar)
        self.actionLo_que_he_hecho.triggered.connect(self.showLogPanel)
        self.actionAtajos_con_el_teclado_2.triggered.connect(self.helpOption)
        self.actionMochila.triggered.connect(self.showMochila)

        #Margenes 0
        self.gridLayout_7.setMargin(0)
        self.gridLayout_7.setSpacing(0)
        self.gridLayout_2.setMargin(0)
        self.gridLayout_2.setSpacing(0)
        self.gridLayout_8.setMargin(0)
        self.gridLayout_8.setSpacing(0)
        self.gridLayout_10.setMargin(0)
        self.gridLayout_10.setSpacing(0)
        
        #Crear el tree widget 
        self.Log_treeWidget
        self.item0=QtGui.QTreeWidgetItem(self.Log_treeWidget)
        
        # Crear el grid de la mochila
        #self.Mochila = QtGui.QGridLayout(self.Mochila)
        #self.Mochila.setObjectName("Mochila")
        
        # Crear el grid del show panel
#        self.grid_show_panel = QtGui.QGridLayout(self.show_panel)
#        self.grid_show_panel.setObjectName("grid_show_panel")
        
        # Contenedores de labels
        self._canvas_lbls = []
        self._mochila_lbls = []
        self._show_panel_lbls = []
        self.hideLogPanel()
        self.instrucciones_widget.hide()
        self.showPanelFrame = ABJFrame(self.Escena)
        self.showPanelFrame.setStyleSheet("border:2px solid gray; border-radius:10px; background:white; selection-background-color:darkgray;")
        self.showPanelFrame.hide()
        self.MochilaContainer.hide()
        
        self.frame.dragMoveEvent = self.dragMoveEventCanvas
        self.frame.dropEvent = self.dropEventCanvas
        
        self.mochila_content.dragMoveEvent = self.dragMoveEventMochila
        self.mochila_content.dropEvent = self.dropEventMochila
        
        self.showPanelFrame.dragMoveEvent = self.dragMoveEventShowPanel
        self.showPanelFrame.dropEvent = self.dropEventShowPanel
                
        #self.instrucciones_widget.hide()
        # Definir funcion de boton --> mover
#        self.moveHero.mouseReleaseEvent = self.mover
#        
#        # Definir funcion de boton --> ligar
#        self.soulBoundHero.mouseReleaseEvent = self.ligar
#        
#        # Definir funcion de boton --> desligar
#        self.desligar.mouseReleaseEvent = self.dligar
#        
#        # Definir funcion de boton --> calificar
#        self.btn_calificar.mouseReleaseEvent = self.calificar
#        
#        # Definir funcion de boton --> buscar / abrir
#        self.btn_buscar.mouseReleaseEvent = self.buscar
#        
#        # Definir funcion de boton --> movimientos aislados del heroe
#        self.upMove.mouseReleaseEvent = self.moveHeroUp#("up")
#        self.downMove.mouseReleaseEvent = self.moveHeroDown#("down")
#        self.leftMove.mouseReleaseEvent = self.moveHeroLeft#("left")
#        self.rightMove.mouseReleaseEvent = self.moveHeroRight#("right")
#        
#        # Definir funcion de boton --> cambio de postura del heroe
#        self.postura1.mouseReleaseEvent = self.posturaChange1
#        self.postura2.mouseReleaseEvent = self.posturaChange2
#        lol = array ([[1,2],[3,4],[5,6]])
#        print lol[0][1]
#        lol[0][1] = 8
#        lol[1][1] = 10
#        lol[2][1] = 220
#        print lol
        # Setup Logico
        self._sel = []
        self._sel_mochila = []
        self._logico = LogicoABJ("idiomas/ES.xml", "Nombre de Prueba")
        self.acceptDrops()
    
    def dragMoveEventCanvas(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()
        isSeleContainer =False
        for lbl in self._canvas_lbls:
            width = lbl.x() + lbl.width()
            height = lbl.y() + lbl.height()
            if (event.pos().x() < width) and (event.pos().x() > lbl.x()) and (event.pos().y() < height) and (event.pos().y() > lbl.y()) and isinstance(lbl._objeto,ITener):                
                self._seleContainer = []
                self._seleContainer.append(lbl._objeto)
                isSeleContainer =True
#                print lbl._objeto
            if(isSeleContainer == True):
                break
                
    
    def dropEventCanvas(self,event):
        if len(self._seleContainer) >0:
#            print self._seleContainer[0] 
            self._sele=[]
            self._sele.append(self._seleContainer[0])
            #self.mover()
            if len(self._sele_mochila) != 0:
                if (isinstance(self._seleContainer[0],IAbrir)):
                    #self.buscar()
                    if self._seleContainer[0].getAbierto():
                        pass
                    else:
                        self.messageDialog("No es posible colocar objetos en un contenedor cerrado","Error")
                        return
                self.dligar()
            else:
                return
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()                        
        print self._sele_mochila
        
    def dragMoveEventMochila(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()
    
    def dropEventMochila(self,event):
        
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()        
        self.ligar()
        print self.mochila_content._lol
    
    def dragMoveEventShowPanel(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()

        
    def dropEventShowPanel(self,event):
        event.setDropAction(QtCore.Qt.MoveAction)
        event.accept()        
        #print self.mochila_content._lol

    def saveToBackpack(self,item):
        print "saveToBackpack"

    def takeOutBackpack(self,item):
        print "item take it of"
    
    def newOption(self):
        print "new file"
        
    def openOption(self):
        """
        Este método se manda a llamar cuando se quiere cargar un nuevo problema
        desde el toolbar, al hacer click en 'Abrir'.
        Para llenar el combo box de los problemas disponibles, escribirlos
        en el archivo: 'listadeproblemas.txt', en el root de esta instalación

        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        selectProblemDialog = QDialog(self)
        selectProblemDialog.setObjectName(QString.fromUtf8("selectProblemDialog"));
        selectProblemDialog.resize(294,133)
        
        #Configuración de los botones del diálogo
        buttonBoxForDialog = QDialogButtonBox(selectProblemDialog)
        buttonBoxForDialog.setGeometry(QRect(60,79,181,51))
        buttonBoxForDialog.setOrientation(Qt.Horizontal)
        buttonBoxForDialog.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)

        #Combo box con las opciones de problemas disponibles a resolver
        problemsOptions = QComboBox(selectProblemDialog)
        problemsOptions.setObjectName(QString.fromUtf8("problemsOptions"))
        problemsOptions.setGeometry(QRect(60,30,170,27))
        problemsOptions.setFrame(True)

        problemsOptions.setCurrentIndex(0);
        QObject.connect(problemsOptions, SIGNAL("activated(QString)"), self.cargaproblema)
        selectProblemDialog.connect(buttonBoxForDialog, SIGNAL("accepted()"), selectProblemDialog, SLOT("accept()"));
        QObject.connect(buttonBoxForDialog, SIGNAL("rejected()"), selectProblemDialog, SLOT("reject()"))

        selectProblemDialog.setWindowTitle(("Problemas disponibles"))
        problemsOptions.clear()
        problemsOptions.addItem("Elige un problema", QVariant(""))
        
        #se abre el archivo que contiene la lista de problemas disponibles
        archivo = open('listadeproblemas.txt')
        
        #se agregan los problemas al combobox
        for line in archivo.readlines():
            line = line.rstrip()
            if line != '' or line !='\n':
                problemsOptions.addItem(line,QVariant(":/problemas/"+line+".py"))
            
        
        problemsOptions.setWhatsThis("Lista de problemas disponibles para resolver")
        selectProblemDialog.setModal(True)
        self._select_dialog = selectProblemDialog
        selectProblemDialog.show()
        
        
    def saveOption(self):
        print "save file"
        self.guardar()
    def cutOption(self):
        print "cut"
        
    def problemDescription(self):
		"""
		Este metodo despliega la descripcion del problema a resolver
		
		@type 	self: Ventana Principal
		@param  self: Referencia a la ventana principal
		"""
	
		#inicializacion del dialogo a desplegar
		dialogo = QDialog(self)
		dialogo.resize(420, 332)
		dialogo.setWindowTitle(('Instrucciones'))
		
		#fondo
		label = QtGui.QLabel(dialogo)
		label.setGeometry(QtCore.QRect(0, 0, 451, 331))
		label.setText(_fromUtf8(""))
		label.setPixmap(QtGui.QPixmap(os.path.abspath("imagenes/instrucciones/" + str(self._prob).lower() + ".png")))
		label.setObjectName(_fromUtf8("label"))
		
		#boton de Ok
		pushButton = QtGui.QPushButton(dialogo)
		pushButton.setGeometry(QtCore.QRect(80, 210, 71, 23))
		pushButton.setObjectName(_fromUtf8("Ok"))
		pushButton.setText("Ok")
		
		#font para mensaje
		font = QFont()
		font.setFamily(QString.fromUtf8("Sans Serif"))
		font.setStyleStrategy(QFont.PreferAntialias)
		font.setPointSize(15)
		
		#la descripcion del problema
		mensaje = QtGui.QLabel(dialogo)
		mensaje.setText(self._logico._problema.getDescripcion())
		mensaje.setGeometry(QtCore.QRect(10, 0, 401, 181))
		mensaje.setObjectName(_fromUtf8("mensaje"))
		mensaje.setFont(font)
		
		#accion de accept
		dialogo.connect(pushButton, SIGNAL("clicked()"), dialogo, SLOT("accept()"))

		#para que no se pueda cliquear nada 
		dialogo.setModal(True)
		dialogo.show() #se despliega el dialogo
        
        
    def copyOption(self):
        print "copy"
    def pasteOption(self):
        print "paste"
    def selectHeroOption(self):
        print "selected hero"
        
    def helpOption(self):
		"""
		Este metodo despliega el dialogo de los keybindigs.

		@type   self: Ventana Principal
		@param  self: Referencia a la ventana principal
		"""
		dialog = QDialog(self)
		dialog.setWindowTitle(('Atajos con el teclado'))
		dialog.resize(591, 370)
		
		#fondo
		label = QtGui.QLabel(dialog)
		label.setGeometry(QtCore.QRect(0, 0, 591, 370))
		label.setText(_fromUtf8(""))
		label.setPixmap(QtGui.QPixmap(os.path.abspath("imagenes/instrucciones/keyboard.jpg")))
		label.setObjectName(_fromUtf8("label"))
		
		botones = QDialogButtonBox(dialog)
		botones.setGeometry(QRect(250,320,91,32))
		#botones.setLayoutDirection(Qt.LeftToRight)
		botones.setOrientation(Qt.Horizontal)
		botones.setStandardButtons(QDialogButtonBox.Ok)
		botones.setCenterButtons(True)
		message = """<h1>     USA EL TECLADO</h1>
			   <p>Selecciona con el mouse objetos en la pantalla y <br />
			   luego presiona los siguientes botones para realizar  <br />
			   distintas acciones:
			   <br />
			   <br />
			   <b>'M' o 'm'</b>: moverte a un objeto<br /> 
			   <b>'A' o 'a'</b>: abrir un objeto<br />
			   <b>'G' o 'g'</b>: guardar un objeto de la escena<br />
			   <b>'S' o 's'</b>: soltar un objeto de la escena<br />
			   <b>'C' o 'c'</b>: cerrar un objeto abierto<br />"""
			   
		label = QtGui.QLabel(str(message), dialog)
		label.setGeometry(QRect(10,10,561,301))
		label.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)

		#Font para el label del texto de los keybindings
		font = QFont()
		font.setFamily(QString.fromUtf8("Sans Serif"))
		font.setStyleStrategy(QFont.PreferAntialias)
		font.setPointSize(15)
		label.setFont(font)
		#label.setStyleSheet("QLabel {}")
		#label.setText(self._logico._problema.getDescripcion())

		dialog.connect(botones, SIGNAL("accepted()"), dialog, SLOT("accept()"))

		dialog.setModal(True)
		dialog.show()
		print "help"
    
    
    def showLogPanel(self):
        self.buttomBar.show()
        
    def showMochila(self):
        self.MochilaContainer.show()
                   
    def messageDialog(self, message,icon):
        """
        Este metodo se puede llamar cuando se quiere desplegar un mensaje
        de error, por favor notar el tamaño del mensaje y ajustarla
        agregando '\n'.
            
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    message: string
        @param    message: mensaje de error a desplegar.
        
        @type    icon: String
        @param   icon: nombre del icono a desplegar (Warning, Error o Success)
        """
        dialog = QDialog(self)
        dialog.setWindowTitle(('ABJ'))
        dialog.resize(391, 148)
        
        botones = QDialogButtonBox(dialog)
        botones.setGeometry(QRect(30,110,351,31))
        botones.setLayoutDirection(Qt.LeftToRight)
        botones.setOrientation(Qt.Horizontal)
        botones.setStandardButtons(QDialogButtonBox.Ok)
        botones.setCenterButtons(True)
        
        
        label = QtGui.QLabel(str(message), dialog)
        label.setGeometry(QRect(100,10,261,81))
        label.setAlignment(Qt.AlignCenter)
        
        icono = QtGui.QLabel(dialog)
        icono.setGeometry(QRect(30,20,51,61))
        icono.setPixmap(QtGui.QPixmap(_fromUtf8("iconos/"+icon+".png")))

        #label.move(1, 22)
        
        dialog.connect(botones, SIGNAL("accepted()"), dialog, SLOT("accept()"))

        #OK = QPushButton("OK", dialog)
        #dialog.connect(OK,SIGNAL("clicked()"),dialog.accept)
        #OK.move(140, 40)
        
        dialog.setModal(True)
        dialog.show()

        
    def hideLogPanel(self):
        """
        ????
        """
        self.buttomBar.hide()
        
            
    def keyPressEvent(self, event):
        """
        Reimplementación del evento Key Press. Hay que definir un
        diccionario de Keys, por el momento implementaré:
            - m = moverse a (mover)
            - g = guardar (ligar)
            - s = soltar (desligar)
            - a = abrir
            - c = cerrar
            
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual

        @type    event: evento del sistema
        @param    event: evento del teclado al presionar una tecla.
        """
        
        
        #Para 'mover'
        if event.text() == 'm' or event.text() =='M':
            ev = self.mover
            self.mover(ev)
        
        #Para 'guardar (ligar)'
        if event.text() == 'g' or event.text() =='G':
            ev = self.ligar
            self.ligar(ev)
        
        #Para 'soltar (desligar)'
        if event.text() == 's' or event.text() =='S':
            ev = self.dligar
            self.dligar(ev)
        
        #Para 'abrir'
        if event.text() == 'a' or event.text() =='A':
            ev = self.buscar
            self.buscar(ev)
        
        #Para 'cerrar', use 'c' de lock
        if event.text() == 'c' or event.text() =='C':
            if len(self._sele) !=0:
                art1 = self._logico._articulo.get(self._logico._genero.get(self._sele[0].getNombre()))
                comando = str("cerrar " + art1 + " " +self._sele[0].getNombre())
                self._logico.runCommand(comando)
                print "\n (y)" + comando
                
                # Refrescar la vista
                self.refresca_grafico()
                
                #Crear item del log
                self.addLogItem(comando)
            else:
                self.messageDialog("No hay objeto seleccionado.","Warning")
                print "No hay objeto seleccionado"

    
    def addLogItem(self, accion): 
        """
        Agrega un elemento al Log
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    accion: string
        @param    comando: cadena de caracteres que se agregara al log.
        """
        comando=""
        imagen=""
        #Generar error
        print str(self._logico._logAction) + "LACOSA" + self._logico._errorMessage
        if self._logico._logAction==-1:            
            self.messageDialog(self._logico._errorMessage, "Warning")
            #self.guardar()
        #Generar log solo sí se ha podido completar la acción
        else:
            if(isinstance(accion, IAccion)):
                comando=accion.getComando()
                imagen=accion.getImagen()
            else:
                comando=accion
                imagen="iconos/abeja-icon2.png"
            
            item=QtGui.QTreeWidgetItem(self.Log_treeWidget)
            self._i=self._i+1
            self.Log_treeWidget.insertTopLevelItem(0,item)
            self.Log_treeWidget.topLevelItem(self._i).setText(0, comando)
            icono = QtGui.QIcon()
            icono.addPixmap(QtGui.QPixmap(_fromUtf8(imagen)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.Log_treeWidget.topLevelItem(self._i).setIcon(0,icono)
            #Concatenar al gran string
            self._actionString+=comando+"\n"
                       

    def guardar(self):
        """
        Guarda las acciones del log en un archivo de texto
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
                
        """
        file = open("Soluciones/"+self._logico._problema.getNombre()+".txt",'w')
        file.write(self._actionString)
        file.close()
        self.messageDialog("Se ha guardado todo exitosamente", "Success")
                
    def moveHeroUp(self, ev):
        """
        Mueve al Heroe para arriba
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("corro hacia el atras poco")
        self.refresca_grafico()
        
        # Regresar el botón a su estado original (no presionado)
        self.upMove.setDown(False)

    def moveHeroDown(self, ev):
        """
        Mueve al Heroe para abajo
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("corro hacia el adelante poco")
        self.refresca_grafico()
        
        # Regresar el botón a su estado original (no presionado)
        self.downMove.setDown(False)

    def moveHeroLeft(self, ev):   
        """
        Mueve al Heroe para la izquierda
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("corro hacia la izquierda poco")
        self.refresca_grafico()
        
        # Regresar el botón a su estado original (no presionado)
        self.leftMove.setDown(False)

    def moveHeroRight(self, ev):
        """
        Mueve al Heroe para la derecha
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("corro hacia la derecha poco")
        self.refresca_grafico()
        
        # Regresar el botón a su estado original (no presionado)
        self.rightMove.setDown(False)

    def posturaChange1(self,ev):
        """
        Cambia la postura al Heroe: Sentado
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("sentarse")
        self.refresca_grafico()
        
    def posturaChange2(self,ev):
        """
        Cambia de postura al Heroe: sentado
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        self._logico.runCommand("pararse")
    
    def connectActions(self):
        """
        Acciones de la gui (fijas, como los botones de la interfaz, barra de herramientas, y acciones del heroe)
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        pass
    
    def cargaproblema(self, prob):
		"""
		Metodo que permite cargar un problema en la parte grafica dependiente de la parte logica.
		@type    self: VentanaPrincipal
		@param    self: referencia al objeto VentanaPrincipal actual

		@type    prob: string
		@param    prob: nombre del problema a resolver
		"""
		self._prob = prob
		self._logico.runCommand("resuelve " + str(prob).lower())
		#Background
		"""
		imagePartialPath = self._logico._problema.getBackground()
		bg = QLabel(self.frame)
		bg.setPixmap(QtGui.QPixmap(imagePartialPath))"""

		#background
		imagePartialPath = self._logico._problema.getBackground()
		part1 = "QFrame{background:url("
		part2 = os.path.abspath(imagePartialPath)
		part3 = ")}" #;border:2px solid gray; border-radius:10px; background:white; selection-background-color:darkgray;
		#CSS for the rest of the application 
		AditionalCSS= "QLabel{background:none;}"  
		cssStyleSheet= part1+part2+part3+AditionalCSS
		cssStyleSheet= cssStyleSheet.replace('\\', '/')
		self.frame.setStyleSheet(QtGui.QApplication.translate("MainWindow", cssStyleSheet, None, QtGui.QApplication.UnicodeUTF8))

		cssMochila = "QLabel:hover{background:rgb(15, 65, 87); border-radius:15px;}"        
		self.mochila_content.setStyleSheet(QtGui.QApplication.translate("MainWindow", cssMochila, None, QtGui.QApplication.UnicodeUTF8))

		# Actualizar pantalla
		self.refresca_grafico()

		# Eliminar labels en el menu de ayuda
		for lb in self._labels_ayuda:
			lb.setParent(None)
		self._labels_ayuda = []

		self.problemDescription()

		# Resolver problema ...
		self._select_dialog.hide()
		self.MochilaContainer.show()
        
        
    def refresca_grafico(self):
        """
        Cada vez que el estado del problema cambia, debe llamarse este metodo para refrescar el estado de la interfaz grafica.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.refresca_canvas()
        self.refresca_mochila()
        #self.refresca_show_panel()
    
    def vacia_show_panel(self):
        """
        Elimina todos los labels que actualmente se encuentren contenidos en el Show Panel
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        for qw in self._show_panel_lbls:
            self.grid_show_panel.removeWidget(qw)
            qw.setParent(None)
            
        self._show_panel_lbls = []
    
    
    def refresca_show_panel(self):
        pass
        """
        Actualiza el estado grafico del elemento Show Panel
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        """self.vacia_show_panel()
        # Listado de los objetos que estan dentro de un
        # contenedor oscuro en el primer nivel
        objetos_en_oscuro = self._logico._problema.getObjetosO1()
        
        for objeto_oscuro in objetos_en_oscuro:
            if objeto_oscuro.esVisible():
                self.pon_show_panel(objeto_oscuro, self.show_panel,False)"""
    
    def pon_show_panel(self, obj, parent, selected):
        """
        Agrega un objeto en el Show Panel
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    obj: Objeto
        @param    obj: el objeto que se agregara al Show Panel (Logico)
        
        @type    parent: QObject
        @param    parent: Componente de pyQT que despliega la VentanaPrincipal
        
        @type    selected: Boolean
        @param    selected: bandera que indica si el objeto a agregar esta o no seleccionado. True = seleccionado, False = no seleccionado.
        """
        # Enviarle el selector del canvas (excluyente con los elementos del canvas)
        nulbl = ABJLabel(None, obj, self._sele, self._logico, self)
        
        # Traer la misma imagen como si estuviera en mochila
        if selected:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagenMochilaSelected()))
        else:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagenMochila()))
            
        self.grid_show_panel.addWidget(nulbl)
        self._show_panel_lbls.append(nulbl)
            
        nulbl.setContextMenuPolicy(Qt.CustomContextMenu)
        
        # Cuando se hace click sobre un objeto del panel se van a cliqueado_showpanel
        QObject.connect(nulbl, SIGNAL("clicked()"), self.cliqueado_showpanel)
        QObject.connect(nulbl, SIGNAL("customContextMenuRequested(QPoint)"),nulbl.contextMenuEvent)
        return nulbl

    def vacia_mochila(self):
        """
        Elimina todos los labels que actualmente se encuentren contenidos en la Mochila
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        
        for qw in self._mochila_lbls:
            self.gridLayout_9.removeWidget(qw)
            qw.setParent(None)
            
        self._mochila_lbls = []
        self._mochilaGrid = array ([[True,True],[True,True],[True,True]])
    def refresca_mochila(self):
        """
        Actualiza el estado grafico del elemento Mochila
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.vacia_mochila()
        objetos_ligados = self._logico._heroe.getObjetos()
        
        
        
        for objeto_ligado in objetos_ligados:
            self.pon_mochila(objeto_ligado, self.Mochila,False)
    
    def pon_mochila(self, obj, parent, selected):
        """
        Agrega un objeto en la Mochila
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    obj: Objeto
        @param    obj: el objeto que se agregara al Show Panel (Logico)
        
        @type    parent: QObject
        @param    parent: Componente de pyQT que despliega la VentanaPrincipal
        
        @type    selected: Boolean
        @param    selected: bandera que indica si el objeto a agregar esta o no seleccionado. True = seleccionado, False = no seleccionado.
        """
        nulbl = ABJLabel(None, obj, self._sele_mochila, self._logico, self, True)
        nulbl.setStyleSheet("border:2px solid white; border-radius:15px; background:rgb(74, 93, 97); no-repeat center;")
        if selected:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagenMochilaSelected()))
        else:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagenMochila()))
        nulbl.setContextMenuPolicy(Qt.CustomContextMenu)
        
        doneMochila =False
        for F1 in range(3):
            for C1 in range(2):
                if(self._mochilaGrid[F1][C1] == True):                    
                    self.gridLayout_9.addWidget(nulbl,F1, C1,1,1)
                    self._mochilaGrid[F1][C1] = False
                    doneMochila=True
                if(doneMochila==True):
                    break
            if(doneMochila==True):
                break
#        self.gridLayout_9.addWidget(nulbl)
        self._mochila_lbls.append(nulbl)
        QObject.connect(nulbl, SIGNAL("clicked()"), self.cliqueado_mochila)
        QObject.connect(nulbl, SIGNAL("clickLabel"), self.cliqueado_mochila)
        QObject.connect(nulbl, SIGNAL("customContextMenuRequested(QPoint)"),nulbl.contextMenuEvent)
        return nulbl
    
    def vacia_canvas(self):
        """
        Elimina todos los labels que actualmente se encuentren contenidos en el Canvas
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        for qw in self._canvas_lbls:
            qw.setParent(None)
            
        self._canvas_lbls = []
        self._lbl_heroe = None
    
    def refresca_canvas(self):
        """
        Actualiza el estado grafico del elemento Canvas
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.vacia_canvas()
        
        # Obtener todos los objetos a mostrar en pantalla
        objetos = self._logico._problema.getObjetos()
        
        #for i in objetos:
        #    print i.getNombre()
        
        # Procesarlos
        for objeto in objetos:
            if objeto.getsImagen().strip() != "":
                if (len(self._sele) > 0) and (objeto.getNombre()==self._sele[0].getNombre()):
                    self.pon_lbl(objeto, self.frame, False,True)
                else:
                    self.pon_lbl(objeto, self.frame, False,False)
                
                
        # Heroe
        self._lbl_heroe = self.pon_lbl(self._logico._heroe, self.frame, True, False)
        self._lbl_heroe.set_heroe()
        
        # Listado de los objetos que estan dentro de un
        # contenedor oscuro en el primer nivel
        objetos_en_oscuro = self._logico._problema.getObjetosO1()
        contenido_index = 0
        
        for lbl in self._canvas_lbls:
            
            obj = lbl._objeto
            
            # Si no es el heroe
            if lbl != self._lbl_heroe:
                
                if obj.esVisible():# and not(obj in objetos_en_oscuro):
                    lbl.show()
                else:
                    lbl.hide()
            else:
                lbl.show()
            lbl.move(obj.getX(), obj.getY())
            
            if (isinstance(obj,ITener)):
                contenedor_actual=obj
                contenido_index = 0
                
            if (not(isinstance(obj,ITener)) and lbl != self._lbl_heroe):
                qpix = obj.getY()-lbl.pixmap().height()
                if (qpix >= 0):
                    lbl.move(obj.getX()+contenido_index*contenedor_actual.getCorrimiento(), qpix)
                    
                contenido_index += 1
            
    def pon_lbl(self, obj, parent, heroe, selected):
        """
        Agrega un objeto en el Canvas
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    obj: Objeto
        @param    obj: el objeto que se agregara al Show Panel (Logico)
        
        @type    parent: QObject
        @param    parent: Componente de pyQT que despliega la VentanaPrincipal
        
        @type    selected: Boolean
        @param    selected: bandera que indica si el objeto a agregar esta o no seleccionado. True = seleccionado, False = no seleccionado.
        """
        nulbl = None
        
        if heroe:
            nulbl = ABJLabel(parent, obj, [], self._logico)
            nulbl.setContextMenuPolicy(Qt.CustomContextMenu)
        else:
            nulbl = ABJLabel(parent, obj, self._sele, self._logico, self)
            
        if selected:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagenSelected())) #si fue seleccionado se cambia la imagen por la de seleccionado
            
        else:
            nulbl.setPixmap(QtGui.QPixmap(obj.getImagen()))
        

        nulbl.setStyleSheet("border:2px solid gray; border-radius:15px;")            
        self._canvas_lbls.append(nulbl)
        if not heroe:
            nulbl.setContextMenuPolicy(Qt.CustomContextMenu)
            QObject.connect(nulbl, SIGNAL("clicked()"), self.cliqueado_canvas)
            QObject.connect(nulbl, SIGNAL("customContextMenuRequested(QPoint)"),nulbl.contextMenuEvent)    
        return nulbl
        
    def cliqueado_canvas(self):
        """
        Procedimiento al haber cliqueado un objeto en el Canvas.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.refresca_canvas()
        
    def cliqueado_mochila(self):
        """
        Procedimiento al haber cliqueado un objeto en la Mochila.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.vacia_mochila()
        objetos_ligados = self._logico._heroe.getObjetos()
        
        if len(self._sele_mochila) >0 :
            #aqui toy
            for objeto_ligado in objetos_ligados:
                if objeto_ligado.getNombre() == self._sele_mochila[0].getNombre():
                    self.pon_mochila(objeto_ligado, self.Mochila, True)
                else:
                    self.pon_mochila(objeto_ligado, self.Mochila, False)
        else:
            self.refresca_mochila()
                
        self.refresca_show_panel()
        
    def cliqueado_showpanel(self):
        """
        Procedimiento al haber cliqueado un objeto en el Show Panel.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.vacia_show_panel()
        
        # Listado de los objetos que estan dentro de un
        # contenedor oscuro en el primer nivel
        objetos_en_oscuro = self._logico._problema.getObjetosO1()
        
        for objeto_oscuro in objetos_en_oscuro:
            if objeto_oscuro.esVisible():
                
                if objeto_oscuro.getNombre() == self._sele[0].getNombre():
                    self.pon_show_panel(objeto_oscuro, self.show_panel,True)
                else:
                    self.pon_show_panel(objeto_oscuro, self.show_panel,False)
                    
        self.refresca_mochila()
        
    def dligar(self, ev=None, action=None):
        """
        Desliga un objeto del Heroe (lo saca de la mochila)
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        if len(self._sele_mochila) != 0:
            
            if len(self._sele) != 0:
                art1 = self._logico._articulo.get(self._logico._genero.get(self._sele_mochila[0].getNombre()))
                art2 = self._logico._articulo.get(self._logico._genero.get(self._sele[0].getNombre()))
                action=None
                action=IAccion(verbo="dejo", imagen="imagenes/acciones/soltar.png", comando="{verbo} {articulo0} {objeto0} en {articulo1} {objeto1}")
                action.articulos.append(art1)
                action.articulos.append(art2)
                action.objetos.append(self._sele_mochila[0].getNombre())
                action.objetos.append(self._sele[0].getNombre())
                
                #comando = str("dejo " + art1 + " " + self._sele_mochila[0].getNombre() + " en " + art2 + " " + self._sele[0].getNombre())
                #print comando                
                self._logico.runCommand(str(action.getComando()))
                
                #Crear item del log
                logItem=QtGui.QTreeWidgetItem(self.Log_treeWidget)
                self.addLogItem(action)
            
                # Vaciar el elemento seleccionado de la mochila
                while len(self._sele_mochila) != 0:
                    self._sele_mochila.pop()
                
                # Refrescar la vista
                self.refresca_grafico()
                
            else:
                art1 = self._logico._articulo.get(self._logico._genero.get(self._sele_mochila[0].getNombre()))
                #comando = str("dejo " + art1 + " " + self._sele_mochila[0].getNombre())
                action=None
                action=IAccion(verbo="dejo", imagen="imagenes/acciones/soltar.png", comando="{verbo} {articulo0} {objeto0}")
                action.articulos.append(art1)
                action.objetos.append(self._sele_mochila[0].getNombre())
                
                
                
                self._logico.runCommand(str(action.getComando()))
                
                #Crear item del log
                logItem=QtGui.QTreeWidgetItem(self.Log_treeWidget)
                self.addLogItem(action)
                 
                # Vaciar el elemento seleccionado de la mochila
                while len(self._sele_mochila) != 0:
                    self._sele_mochila.pop()
                    
                # Refrescar la vista
                self.refresca_grafico()
                
        else:
            self.messageDialog("No has seleccionado un objeto que soltar", "Warning")
            print "No hay objeto (u objetivo) seleccionado, por tanto no se puede desligar nada"
        
    def mover(self, ev=None):
        """
        Mueve al Heroe hacia el objeto seleccionado.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        if len(self._sele) != 0:
            
            art1 = self._logico._articulo.get(self._logico._genero.get(self._sele[0].getNombre()))
            action=None
            action=IAccion(verbo="moverse a", imagen="imagenes/acciones/Moverse a.png", comando="{verbo} {articulo0} {objeto0}")
            action.articulos.append(art1)
            action.objetos.append(self._sele[0].getNombre())
            self._logico.runCommand(str(action.getComando()))
            #print "\n (y) " + comando
            
            #Crear item del log
            self.addLogItem(action)
            
            # Refrescar la vista
            self.refresca_grafico()
            self._lbl_heroe.move(self._logico._heroe.getX(), self._logico._heroe.getY())
        else:
            self.messageDialog("No hay objeto seleccionado,\n por tanto no se puede mover al heroe", "Warning")
            print "No hay objeto seleccionado, por tanto no se puede mover al heroe"
            
        # Regresar el botón a su estado original (no presionado)
        #self.moveHero.setDown(False)
        
        
    def ligar(self, ev=None):
        """
        Agrega en la Mochila del Heroe un objeto seleccionado.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        if len(self._sele) != 0:
            
            art1 = self._logico._articulo.get(self._logico._genero.get(self._sele[0].getNombre()))
            action=None
            action=IAccion(verbo="agarro", imagen="imagenes/acciones/Agarrar.png", comando="{verbo} {articulo0} {objeto0}")
            action.articulos.append(art1)
            action.objetos.append(self._sele[0].getNombre())
                
            #comando = str("agarro " + art1 + " " + self._sele[0].getNombre())
            self._logico.runCommand(str(action.getComando()))
            
            #Crear item del log
            self.addLogItem(action)
            
            #print "\n (y) " + comando
            
            # Deseleccionar
            while len(self._sele) != 0:
                self._sele.pop()
            
            # Refrescar la vista
            self.refresca_grafico()
            
        else:
            self.messageDialog("No hay objeto seleccionado,\n por tanto no se puede agarrar nada", "Warning")
            print " (!) No hay objeto seleccionado, por tanto no se puede ligar nada"
            
        # Regresar el botón a su estado original (no presionado)
        #self.soulBoundHero.setDown(False)
    
    def calificar(self, ev=None):
        """
        Verifica que el estado actual del problema (si esta resuelto o si aun le falta)
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        resultado = self._logico._problema.califica()
        res_s = QString()
        
        if len(resultado) == 0:
            res_s.append(" Bien resuelto patojo!!")
        else:
            for i in resultado:
                res_s.append(QString.fromUtf8(i) + "\n")
        
        QMessageBox.information(self, "Resultados", QString.fromUtf8(res_s)) # <--------------------------------------------------------------------------------------------- DIALOGO
        
        # Regresar el botón a su estado original (no presionado)
        #self.btn_calificar.setDown(False)
        return
    
    def buscar(self, ev=None):
        """
        Busca dentro del contenedor seleccionado.
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        
        @type    ev: QMouseEvent 
        @param    ev: evento del raton al aplicar sobre el boton
        """
        if len(self._sele) != 0:
            if(isinstance(self._sele[0], IAbrir)):
                art1 = self._logico._articulo.get(self._logico._genero.get(self._sele[0].getNombre()))
                #comando = str("abro " + art1 + " " + self._sele[0].getNombre())
                action=IAccion(verbo="abro", imagen="imagenes/acciones/abrir.png", comando="{verbo} {articulo0} {objeto0}")
                action.articulos.append(art1)
                action.objetos.append(self._sele[0].getNombre())
                self._logico.runCommand(str(action.getComando()))
                #print "\n (y) " + comando
                
                #Crear item del log
                self.addLogItem(action)
                
                # Refrescar la vista
                self.refresca_grafico()
            else:
                self.messageDialog("Ese objeto no puede abrirse.", "Warning")
        else:
            self.errorDialog("No hay objeto seleccionado,\n por tanto no se puede buscar nada", "Warning")
            print " (!) No hay objeto seleccionado, por tanto no se puede buscar nada"
        
        # Regresar el botón a su estado original (no presionado)
        #self.btn_buscar.setDown(False)
        
        
    def main(self):
        """
        Proceso principal para correr el programa grafico
        @type    self: VentanaPrincipal
        @param    self: referencia al objeto VentanaPrincipal actual
        """
        self.showMaximized()
        self.show()
        
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    principal = VentanaPrincipal()
    principal.openOption()
    #principal.cargaproblema("casa")
    principal.main()
    app.exec_()
